package com.cy.jt.security.config;

import com.cy.jt.security.config.handle.DefaultAccessDeniedExceptionHandler;
import com.cy.jt.security.config.handle.DefaultAuthenticationEntryPoint;
import com.cy.jt.security.config.handle.JsonFailureHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/*
* 由@Configuration注解描述的类位spring中的配置类,配置类会在spring工程启动时优先加载
* 在配置类中通常会对第三方资源进行初始配置
* @EnableGlobalMethodSecurity 注解由SpringSecurity提供,用于描述权限配置类,告诉
* 系统底层在启动时,进行访问权限的初始化配置
* * 1)Enable-启用
 * 2)Global-全局
 * 3)Method-方法
 * 4)Security-安全
* */
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public class SecuConfig extends WebSecurityConfigurerAdapter {
    /*对http请求的安全控制进行配置*/
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //super.configure(http);
        //1.关闭跨域攻击，不关闭容易出错
        http.csrf().disable();
        //2.配置登录url(登录表单使用哪个页面)
        http.formLogin()
                //设置登陆页面
                .loginPage("/login.html")
                //设置登陆请求处理地址(对应form表单中的action),登陆时会访问UserDetailService对象
                .loginProcessingUrl("/login")
                //设置请求用户名参数为username(默认就是username，可以自己修改，需要与表单同步)
                .usernameParameter("username")
                //请求请求密码参数为password(默认就是password，可以自己修改，需要与表单同步)
                .passwordParameter("password")
                //设置登陆成功跳转页面(默认为/index.html)
//                .successHandler(new RedirectSuccessHandler("https://www.baidu.com/"))
//                .successHandler(new JsonSuccessHandler())
                .defaultSuccessUrl("/index.html")
                //登陆失败访问的页面（默认为/login.html?error）
//                .failureHandler(new RedirectFailureHandler("/login.html"));
                .failureHandler(new JsonFailureHandler());
                //.failureUrl("/login.html?error");
        http.logout().logoutUrl("/logout").logoutSuccessUrl("/login.html?logout");
        //设置需要认证与拒绝访问的异常处理器
        http.exceptionHandling()
                .authenticationEntryPoint(//没有认证时执行
                        new DefaultAuthenticationEntryPoint())
                .accessDeniedHandler(//没有授权时执行
                        new DefaultAccessDeniedExceptionHandler());
        //3.旅行登录url(不需要认证就可以访问)
        http.authorizeRequests()
                //设置要放行的咨询
                .antMatchers("/login.html","/images/**").permitAll()//允许直接访问
                .anyRequest().authenticated();//除了以上资源必须认证才可以访问

    }

    /*
    * @Bean 注解通常会在 @Configuration 注解描述的类中描述方法
    * 用于告诉spring框架这个方法的返回值会交给spring管理,并给spring管理的这个
    * 对象起个默认名字,这个名字与方法名相同,当然也可以通过 @Bean注解起名字
    * */
    @Bean//对象名默认为方法名
//    @Bean("bcPasswordEnc")//bean对象名字为bcPasswordEnc
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

}
